package top.codecrab.arrayUnsafe;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CopyOnWriteArraySet;

/**
 * @author codecrab
 * @since 2021年06月30日 9:51
 */
public class ListUnsafeDemo {

    /**
     * 与List同理
     */
    public static void main(String[] args) {
        Map<String, String> map = new ConcurrentHashMap<>();
        for (int i = 1; i <= 30; i++) {
            new Thread(() -> {
                map.put(Thread.currentThread().getName(), UUID.randomUUID().toString().substring(0, 8));
                System.out.println(map);
            }, String.valueOf(i)).start();
        }
    }

    /**
     * 与List同理，new CopyOnWriteArraySet<>() 其实底层就是 new CopyOnWriteArrayList<>()
     */
    private static void testSet() {
        Set<String> set = new CopyOnWriteArraySet<>();
        for (int i = 1; i <= 30; i++) {
            new Thread(() -> {
                set.add(UUID.randomUUID().toString().substring(0, 8));
                System.out.println(set);
            }, String.valueOf(i)).start();
        }
    }

    /**
     * ArrayList是线程不安全的，Vector是线程安全的，但是ArrayList是1.2版本出现的，Vector是1.0版本的
     * 有线程安全的list了，那么出现ArrayList的目的是为了提高性能。
     * 如何解决ArrayList的并发情况下不安全问题(ConcurrentModificationException，并发修改异常)：
     * <p>
     * （1）、new Vector<>()，加 synchronized 的实现，最基础的一种方法，性能浪费太多。
     * <p>
     * （2）、Collections.synchronizedList(new ArrayList<>())，底层也是 synchronized。
     * <p>
     * （3）、new CopyOnWriteArrayList<>()，底层使用读写覆盖，有一个非公平锁，添加元素时，先拷贝原数组，顺带把长度+1，
     * 然后把最后一个位置的元素重新赋值为出传入的值，再覆盖原数组，也就是把原来得数组引用修改为引用刚才拷贝好的新数组
     */
    private static void testList() {
        List<String> list = new CopyOnWriteArrayList<>();
        for (int i = 1; i <= 30; i++) {
            new Thread(() -> {
                list.add(UUID.randomUUID().toString().substring(0, 8));
                System.out.println(list);
            }, String.valueOf(i)).start();
        }
    }
}
